import pygame, sys, random, time, copy

#常量
from pygame.locals import *
UP, DOWN, LEFT, RIGHT = '向上', '向下', '向左', '向右'
#               R    G    B
PURPLE      = (255,   0, 255)
ORANGE      = (255, 128,   0)
YELLOW      = (255, 255,   0)
BLUE        = (  0,   0, 255)
GREEN       = (  0, 255,   0)
BLACK       = (  0,   0,   0)
RED         = (255,   0,   0)
DARKGRAY    = ( 70,  70,  70)
WHITE       = (255, 255, 255)

FPS = 30
WINDOWWIDTH = 800
WINDOWHEIGHT = 600
WINDOWCAPTION = '从底下选择颜色给左上角着色'
FONTFILENAME = 'res/msyh.ttc'
FONTSIZE = 20
ICONFILENAME = 'res/gameicon.png'


BOXSIZE = 60
BOARDSIZE = 6
MAXLIFE = 10
PALETTEGAPSIZE = 10
PALETTESIZE = 45
COLORSCHEMES = (((150, 200, 255), RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE),)
bgColor = COLORSCHEMES[0][0]
paletteColors = COLORSCHEMES[0][1:]
#终止程序
def terminate():
    pygame.quit()
    sys.exit()
#关闭窗口或按Esc键退出程序
def checkForQuit():
    for event in pygame.event.get(QUIT):
        terminate()
    for event in pygame.event.get(KEYUP):
        if event.key == K_ESCAPE:
            terminate()
        else:
            pygame.event.post(event)
def leftTopPixelCoordOfBox(boxx, boxy):
    xmargin = (WINDOWWIDTH - BOARDSIZE*BOXSIZE) // 2
    ymargin = (WINDOWHEIGHT - BOARDSIZE*BOXSIZE) // 2
    return (boxx*BOXSIZE+xmargin, boxy*BOXSIZE+ymargin)
def drawBoard(board, transparency=255):
    tempSurf =  pygame.Surface(DISPLAYSURFACE.get_size())
    tempSurf = tempSurf.convert_alpha()
    tempSurf.fill((0,0,0,0))
    for x in range(BOARDSIZE):
        for y in range(BOARDSIZE):
            left, top = leftTopPixelCoordOfBox(x, y)
            r, g, b = paletteColors[board[x][y]]
            pygame.draw.rect(tempSurf, (r, g, b, transparency), (left, top, BOXSIZE, BOXSIZE))
    left, top = leftTopPixelCoordOfBox(0, 0)
    pygame.draw.rect(tempSurf, BLACK, (left-1, top-1, BOXSIZE*BOARDSIZE+1, BOXSIZE*BOARDSIZE+1), 1)
    DISPLAYSURFACE.blit(tempSurf, (0, 0))
def drawPalettes():
    numColors = len(paletteColors)
    xmargin = (WINDOWWIDTH - (PALETTESIZE*numColors + PALETTEGAPSIZE*(numColors-1))) // 2
    for i in range(numColors):
        left = xmargin + i * (PALETTESIZE+PALETTEGAPSIZE)
        top = WINDOWHEIGHT - PALETTESIZE - 10
        pygame.draw.rect(DISPLAYSURFACE, paletteColors[i], (left, top, PALETTESIZE, PALETTESIZE))
        pygame.draw.rect(DISPLAYSURFACE, bgColor, (left+2, top+2, PALETTESIZE-4, PALETTESIZE-4), 2)
def getColorOfPaletteAt(positionxy):
    x, y = positionxy
    numColors = len(paletteColors)
    xmargin = (WINDOWWIDTH - (PALETTESIZE*numColors + PALETTEGAPSIZE*(numColors-1))) // 2
    for i in range(numColors):
        left = xmargin + i * (PALETTESIZE+PALETTEGAPSIZE)
        top = WINDOWHEIGHT - PALETTESIZE - 10
        r = pygame.Rect(left, top, PALETTESIZE, PALETTESIZE)
        if r.collidepoint(x, y):
            return i
    return None
def generateRandomBoard():
    board = []
    for x in range(BOARDSIZE):
        column = []
        for y in range(BOARDSIZE):
            column.append(random.randint(0, len(paletteColors)-1))
        board.append(column)
    return board
def floodFill(board, oldColor, newColor, x, y):
    if oldColor == newColor or board[x][y] != oldColor:
        return
    board[x][y] = newColor
    if x > 0:
        floodFill(board, oldColor, newColor, x-1, y)
    if x < BOARDSIZE-1:
        floodFill(board, oldColor, newColor, x+1, y)
    if y > 0:
        floodFill(board, oldColor, newColor, x, y-1)
    if y < BOARDSIZE-1:
        floodFill(board, oldColor, newColor, x, y+1)
def floodAnimation(board, paletteClicked, animationSpeed=25):
    origBoard = copy.deepcopy(board)
    floodFill(board, board[0][0], paletteClicked, 0, 0)
    for transparency in range(0, 255, animationSpeed):
        drawBoard(origBoard)
        drawBoard(board, transparency)
        pygame.display.update()
        FPSCLOCK.tick(FPS)
def hasWon(board):
    for x in range(BOARDSIZE):
        for y in range(BOARDSIZE):
            if board[0][0] != board[x][y]:
                return False
    return True
def runGame():
    score, helpMode, gameIsOver = 0, True, False
    mouseDownPosition, mouseUpPosition = None, None
    paletteClicked = None
    mainBoard = generateRandomBoard()
    while True:
        checkForQuit()#检查来自鼠标或键盘的退出事件，结束程序
        
        #在内存绘制
        DISPLAYSURFACE.fill(bgColor)
        drawBoard(mainBoard)
        drawPalettes()
        
        
        #检测鼠标动作和键盘操作事件，进行登记或直接处理
        for event in pygame.event.get():
            if event.type == MOUSEBUTTONUP:
                mouseUpPosition = event.pos
                paletteClicked = getColorOfPaletteAt(mouseUpPosition)
            elif event.type == KEYUP:
                if event.key == K_h: #按h键打开或关闭帮助模式
                    helpMode = not helpMode
                    
        #进行事件处理
        if paletteClicked != None:
            floodAnimation(mainBoard, paletteClicked)
        if hasWon(mainBoard):#这一轮游戏结束的条件
            gameIsOver = True
            
        if helpMode: # 帮助模式下，做提醒
            ...
        if gameIsOver:
            return
        #所有内容绘制到屏幕
        pygame.display.update()
        FPSCLOCK.tick(FPS)
def inkspill():
    #初始化    
    global DISPLAYSURFACE, FPSCLOCK, BASICFONT, BASICSOUND
    pygame.init()
    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURFACE = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
    pygame.display.set_caption(WINDOWCAPTION)
    pygame.display.set_icon(pygame.image.load(ICONFILENAME))    
    BASICFONT = pygame.font.Font(FONTFILENAME, FONTSIZE)

    
    
    while True:
        runGame()
  
if __name__ == '__main__':
    inkspill()